
library ieee;
  use ieee.std_logic_1164.all;
  use IEEE.numeric_std.all;
  
package sha_pack is
 
function rrot(input : std_logic_vector; value : integer) return std_logic_vector;
function rshft(input : std_logic_vector; value : integer) return std_logic_vector;
function Sigma0(input : std_logic_vector) return std_logic_vector;
function Sigma1(input : std_logic_vector) return std_logic_vector;
function Sig0(input : std_logic_vector) return std_logic_vector;
function Sig1(input : std_logic_vector) return std_logic_vector;
function addu(input1 : std_logic_vector; input2 : std_logic_vector) return std_logic_vector;
function ch_fun(in1, in2, in3 : std_logic_vector) return std_logic_vector;

constant sha256_rounds : integer := 64;
constant sha512_rounds : integer := 80;

constant sha256_words : integer := 16; 
constant sha512_words : integer := 32;
end;
-------------------------------------------------------------------------------
package body sha_pack is

function rrot(input : std_logic_vector; value : integer) return std_logic_vector is 
-- return (x >>> n) | (x << (32-n)); }
  begin
  return input(value-1 downto 0) & 
       input(input'length -1 downto value);
end function;
-------------------------------------------------------------------------------
function rshft(input : std_logic_vector; value : integer) return std_logic_vector is 
-- return (x >>> n) | (x << (32-n)); }
variable zeros : std_logic_vector(63 downto 0);
  begin
  zeros := (others => '0');
  return zeros(value -1 downto 0) & 
       input(input'length -1 downto value);
end function;
-------------------------------------------------------------------------------
function Sigma0(input : std_logic_vector) return std_logic_vector is
-- return Sha256.ROTR(2,  x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); 
  begin

  return (rrot(input, 2)) xor (rrot(input, 13)) xor (rrot(input, 22));
  
end function;
-------------------------------------------------------------------------------
function Sigma1(input : std_logic_vector) return std_logic_vector is
-- return Sha256.ROTR(6,  x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); 
  begin

  return (rrot(input, 6)) xor (rrot(input, 11)) xor (rrot(input, 25));
end function;
-------------------------------------------------------------------------------
function Sig0(input : std_logic_vector) return std_logic_vector is
-- return Sha256.ROTR(2,  x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); 
  begin

  return rrot(input, 7) xor rrot(input, 8) xor rrot(input, 22) xor("000" & input(input'length -1 downto 3));
end function;
-------------------------------------------------------------------------------
function Sig1(input : std_logic_vector) return std_logic_vector is
-- return Sha256.ROTR(6,  x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); 
  begin

  return rrot(input, 6) xor rrot(input, 11) xor rrot(input, 25);
end function;
-------------------------------------------------------------------------------
function ch_fun(in1, in2, in3 : std_logic_vector) return std_logic_vector is
--(e and f) xor ((not e) and g)
begin
  return (in1 and in2) xor ((not in1) and in3);
end function;
-------------------------------------------------------------------------------
function addu(input1 : std_logic_vector; input2 : std_logic_vector) return std_logic_vector is
begin
  return std_logic_vector(unsigned(input1) + unsigned(input2));
end function;


end package body;
